


/*global window, $, air, JSLINT, fDate, console */

(function() {
	
	/* private properties */
	var CL,
		
		optionDefs = [
			{ id: "passfail", desc: "Stop on first error", enabled: false },
			{ id: "white", desc: "Strict white space", enabled: true },
			{ id: "browser", desc: "Assume a browser", enabled: false },
			{ id: "widget", desc: "Assume a Yahoo Widgets", enabled: false },
			{ id: "sidebar", desc: "Assume Windows Sidebar Gadget", enabled: false },
			{ id: "rhino", desc: "Assume Rhino", enabled: false },
			{ id: "safe", desc: "Safe Subset", enabled: false },
			{ id: "adsafe", desc: "ADsafe", enabled: false },
			{ id: "debug", desc: "Tolerate debugger statements", enabled: false },
			{ id: "evil", desc: "Tolerate eval", enabled: false },
			{ id: "cap", desc: "Tolerate HTML case", enabled: false },
			{ id: "on", desc: "Tolerate HTML event handlers", enabled: false },
			{ id: "fragment", desc: "Tolerate HTML fragments", enabled: false },
			{ id: "laxbreak", desc: "Tolerate sloppy line breaking", enabled: false },
			{ id: "forin", desc: "Tolerate unfiltered for in", enabled: false },
			{ id: "sub", desc: "Tolerate inefficient subscripting", enabled: false },
			{ id: "css", desc: "Tolerate CSS workarounds", enabled: false },
			{ id: "undef", desc: "Disallow undefined variables", enabled: true },
			{ id: "nomen", desc: "Disallow leading _ in identifiers", enabled: true },
			{ id: "eqeqeq", desc: "Disallow == and !=", enabled: true },
			{ id: "plusplus", desc: "Disallow ++ and --", enabled: false },
			{ id: "bitwise", desc: "Disallow bitwise operators", enabled: false },
			{ id: "regexp", desc: "Disallow . in RegExp literals", enabled: false },
			{ id: "onevar", desc: "Allow only one var statement per function", enabled: false },
			{ id: "strict", desc: 'Require "use strict";', enabled: false },
			{ id: "newcap", desc: "Require Initial Caps for constructors", enabled: true }
		],
		
		selectedOptions = [];
	
	
	/* private methods */
	
	// reads a file from the disk
	function readFile(file) {
		var str, fs = new air.FileStream();
		fs.open(file, air.FileMode.READ);
		str = fs.readMultiByte(file.size, air.File.systemCharset);
		fs.close();
		return str;
	}
	
	// adds *.js files and directories recursively
	function addFile(file, base) {
		if (file.isDirectory) {
			var files = file.getDirectoryListing();
			for (var i = 0; i < files.length; i += 1) {
				addFile(files[i], base);
			}
		}
		else if (file.url.substr(file.url.length-3) === ".js" && typeof CL.files[file.url] === "undefined") {
			CL.files[file.url] = { modDate:file.modificationDate, friendlyUrl:file.url.replace(base,'') };
			CL.linting = true;
		}
	}
	
	// drops 
	function getFileBase(url) {
		var ix = url.lastIndexOf('/');
		return url.substr(0,ix);
	}
	
	function getOptionsObj() {
		var obj = {};
		$.each(optionDefs, function(){
			obj[this.id] = this.enabled;
		});
		return obj;
	}
	
	
	
	CL = {
		
		/* public properties */
		files : {},
		lint : {},
		optionDefinitions : optionDefs,
		linting : false,
		
		/* public methods */
		setOption : function(id, value) {
			$.each(optionDefs, function(){
				if (this.id === id) {
					this.enabled = !!value;
					return false;
				}
			});
		}, 
		
		// add a path to be watched 
		addWatchedPath : function(path) {
			addFile(path, getFileBase(path.url));
		},
		
		// check the known files for lint
		checkLint : function(force) {
			var url, file, js, valid;
			for (url in CL.files) {
				file = new air.File(url);
				if (file.modificationDate > CL.files[url].modDate || force === true) {
					js = readFile(file);
					if (js) {
						valid = JSLINT(js, getOptionsObj());
						if(!valid) {
							CL.lint[url] = {valid:valid,errors:JSLINT.errors};
						}
						else {
							CL.lint[url] = {valid:valid,errors:false};
						}
					}
				}
			}
		}
		
	};
	window.CL = CL;
	
})();